package com.nsproject.client;

import android.content.Context;
import android.util.Log;

import com.seveninvensun.logic.util.AppUtil;
import com.seveninvensun.sdk.Point3D;
import com.seveninvensun.sdk.PointF;
import com.seveninvensun.sdk.api.CalibrationStatusCallback;
import com.seveninvensun.sdk.api.IStartCallback;
import com.seveninvensun.sdk.api.ITrackerClient;
import com.seveninvensun.sdk.api.ITrackerClientDebug;
import com.seveninvensun.sdk.api.ITrackerClientPlus;
import com.seveninvensun.sdk.api.ServerConnectCallback;
import com.seveninvensun.sdk.api.TrackerCreator;
import com.seveninvensun.sdk.entity.EyeDataBasic;
import com.seveninvensun.sdk.entity.StartParam;
import com.seveninvensun.sdk.entity.TrackerResult;

/**
 * @Author: bixj
 * @Date: 2024/1/22 17:52.
 * @Description:
 */
public class TrackerApi {
    private static final String TAG = "7InTracker";
    private Context mContext;
    private ITrackerClient trackerClient;
    private String mErrorMessage = "";
    private boolean mConnectState = false;
    private boolean mStartState = false;
    private int calibPercent = 0;
    private int calibFinishCode = -1;


    //
    private final ServerConnectCallback mServerConnectCallback = new ServerConnectCallback() {
        @Override
        public void onServerConnected(boolean b) {
            mConnectState = b;
            if (b) {
                int code = doStart();
                if (code != 0) {
                    Log.w(TAG, "onServerConnected: doStart error, code=" + code);
                }
            }
        }
    };

    private final CalibrationStatusCallback mCalibrationStatusCallback = new CalibrationStatusCallback() {
        @Override
        public void onFinishCalPoint(int i, int code) {
            calibFinishCode = code;
        }

        @Override
        public void onCalProcess(int i, int percent) {
            calibPercent = percent;
        }
    };

    public void initial(Context context) {
        mContext = context;
        trackerClient = TrackerCreator.getTracker(context, "", "", "");
    }

    // 启动+停止命令相关
    public int start() {
        return doConnect();
    }

    public int release() {
        TrackerResult result = trackerClient.release();
        if (!result.getSuccess()) {
            Log.w(TAG, "release: release error, " + result);
        }
        result = trackerClient.disconnect();
        if (!result.getSuccess()) {
            Log.w(TAG, "release: disconnect error, " + result);
        }
        Log.i(TAG, "release: release success");
        return 0;
    }

    public String getEyeData() {
        if (!mConnectState) {
            mErrorMessage = "connect service error";
            return "-1";
        }
        if (!mStartState) {
            mErrorMessage = "service start error";
            return "-1";
        }
        final EyeDataBasic eyeDataBasic = trackerClient.getEyeData();
        if (eyeDataBasic == null) {
            mErrorMessage = "eyeDataBasic null";
            return "";
        }
        return eyeDataBasicToString(eyeDataBasic);
    }

    // 校准相关
    public int startCalibration(float minX, float maxX, float minY, float maxY, int calibCount) {
        final ITrackerClientPlus clientPlus = (ITrackerClientPlus) trackerClient;
        TrackerResult result = clientPlus.setDefaultCalibration(minX, maxX, minY, maxY);
        if (!result.getSuccess()) {
            mErrorMessage = result.getMessage();
            Log.w(TAG, "startCalibration: setDefaultCalibration error, " + result);
            return result.getCode();
        }

        result = clientPlus.startCalibration(calibCount);
        if (!result.getSuccess()) {
            mErrorMessage = result.getMessage();
            Log.w(TAG, "startCalibration: startCalibration error, " + result);
            return result.getCode();
        }
        return 0;
    }

    public int startCalibrationPoint(int index, float leftX, float leftY, float rightX, float rightY) {
        calibPercent = 0;
        calibFinishCode = -1;
        final ITrackerClientPlus clientPlus = (ITrackerClientPlus) trackerClient;
        final TrackerResult result = clientPlus.startCalibrationPoint(index, leftX, leftY, rightX, rightY, mCalibrationStatusCallback);
        if (!result.getSuccess()) {
            mErrorMessage = result.getMessage();
            Log.w(TAG, "startCalibrationPoint: startCalibrationPoint error, " + result);
            return result.getCode();
        }
        return 0;
    }

    public int cancelCalibrationPoint() {
        final ITrackerClientPlus clientPlus = (ITrackerClientPlus) trackerClient;
        final TrackerResult result = clientPlus.cancelCalibrationPoint();
        if (!result.getSuccess()) {
            mErrorMessage = result.getMessage();
            Log.w(TAG, "cancelCalibrationPoint: cancelCalibrationPoint error, " + result);
            return result.getCode();
        }
        return 0;
    }

    public int completeCalibration() {
        final ITrackerClientPlus clientPlus = (ITrackerClientPlus) trackerClient;
        final TrackerResult result = clientPlus.completeCalibration();
        if (!result.getSuccess()) {
            mErrorMessage = result.getMessage();
            Log.w(TAG, "completeCalibration: completeCalibration error, " + result);
            return result.getCode();
        }
        return 0;
    }

    public int getCalibPercent() {
        return calibPercent;
    }

    public int getCalibFinishCode() {
        return calibFinishCode;
    }

    public String getErrorMessage() {
        return mErrorMessage;
    }

    private int registerImageCallback(){
        final ITrackerClientPlus clientPlus = (ITrackerClientPlus) trackerClient;
        final TrackerResult result = clientPlus.registerCameraImageCallback();
        if (!result.getSuccess()) {
            mErrorMessage = result.getMessage();
            Log.w(TAG, "registerImageCallback: registerCameraImageCallback error, " + result);
            return result.getCode();
        }
        return 0;
    }

    private int unregisterImageCallback(){
        final ITrackerClientPlus clientPlus = (ITrackerClientPlus) trackerClient;
        final TrackerResult result = clientPlus.unregisterCameraImageCallback();
        if (!result.getSuccess()) {
            mErrorMessage = result.getMessage();
            Log.w(TAG, "unregisterImageCallback: unregisterCameraImageCallback error, " + result);
            return result.getCode();
        }
        return 0;
    }

    public int saveImage(String imageName) {
        final ITrackerClientDebug clientDebug = (ITrackerClientDebug) trackerClient;
        final TrackerResult result = clientDebug.saveImage(3, imageName);
        if (!result.getSuccess()) {
            mErrorMessage = result.getMessage();
            Log.w(TAG, "saveImage: saveImage error, " + result);
            return result.getCode();
        }
        return 0;
    }

    // 连接service
    private int doConnect() {
        TrackerResult result = trackerClient.connect(mServerConnectCallback);
        if (!result.getSuccess()) {
            mErrorMessage = result.getMessage();
            Log.w(TAG, "doConnect: connect error, " + mErrorMessage);
            return result.getCode();
        }
        return 0;
    }

    // 启动
    private int doStart() {
        final StartParam startParam = new StartParam();
        startParam.setEyeType(3);
        startParam.setUserId("Guest");
        final TrackerResult result = trackerClient.start(startParam, new IStartCallback() {
            @Override
            public void onState(int code, String msg) {
                mErrorMessage = "";
                if (code != 0) {
                    mStartState = false;
                    mErrorMessage = "code=" + code + ", message=" + msg;
                    Log.w(TAG, "onState: code=" + code + ", message=" + msg);
                    return;
                }
                mStartState = true;
            }
        });
        if (!result.getSuccess()) {
            Log.w(TAG, "start: start error, " + result);
            mErrorMessage = result.getMessage();
            return result.getCode();
        }
        return 0;
    }

    private static final String splitChar = "#";

    private String eyeDataBasicToString(EyeDataBasic eyeDataBasic) {
        int gazeValid = eyeDataBasic.gazePointIsValid() ? 1 : 0;
        final Point3D gazePoint = eyeDataBasic.getGazePoint();
        int leftPupilValid = eyeDataBasic.leftPupilCenterIsValid() ? 1 : 0;
        final PointF leftPupilCenter = eyeDataBasic.getLeftPupilCenter();
        int rightPupilValid = eyeDataBasic.rightPupilCenterIsValid() ? 1 : 0;
        final PointF rightPupilCenter = eyeDataBasic.getRightPupilCenter();

        return "7In gaze" + splitChar + gazeValid + splitChar +
            gazePoint.getX() + splitChar + gazePoint.getY() + splitChar + gazePoint.getZ() + splitChar +
            "leftPupil" + splitChar + leftPupilValid + splitChar +
            leftPupilCenter.getX() + splitChar + leftPupilCenter.getY() + splitChar +
            "rightPupil" + splitChar + rightPupilValid + splitChar +
            rightPupilCenter.getY() + splitChar + rightPupilCenter.getY();
    }


}
